import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import * as XLSX from 'xlsx'
import * as dfd from 'danfojs'
import type { ComparisonResult, ColumnConfig, SortConfig } from './useExcelData'

export function useExcelExport() {
  // 下载动画状态
  const showDownloadAnimation = ref(false)
  const downloadProgress = ref(0)
  const downloadStage = ref('准备中...')

  // 预处理的导出数据
  const preparedExportData = ref<{
    workbook: XLSX.WorkBook | null
    ready: boolean
    config: {
      headers1: string[]
      headerMap: Map<string, number>
      sortFieldIndices: number[]
      totalRows: number
    } | null
  }>({
    workbook: null,
    ready: false,
    config: null,
  })

  // 获取差异类型的文本描述
  const getDiffTypeText = (type: string): string => {
    switch (type) {
      case 'different':
        return '内容不同'
      case 'only-in-file1':
        return '仅在文件1中'
      case 'only-in-file2':
        return '仅在文件2中'
      default:
        return type
    }
  }

  // 标准化值以进行比较
  const normalizeValue = (value: any): string => {
    if (value === null || value === undefined) {
      return ''
    }
    return String(value).toLowerCase().trim().replace(/\s+/g, ' ')
  }

  // 提前准备导出数据的函数
  const prepareExportData = async (
    comparisonResult: ComparisonResult | null,
    excel1Data: any[],
    excel2Headers: string[],
    sortConfigs: SortConfig[],
  ) => {
    if (!comparisonResult || !excel1Data.length) {
      preparedExportData.value.ready = false
      return
    }

    try {
      const wb = XLSX.utils.book_new()
      const headers1 = excel1Data[0] || []

      if (headers1.length > 0) {
        const sortFieldIndices: number[] = []
        for (const config of sortConfigs) {
          const index = headers1.findIndex((h: string) => h === config.field)
          if (index !== -1) {
            sortFieldIndices.push(index)
          }
        }

        const headerMap: Map<string, number> = new Map()
        excel2Headers.forEach((header, index) => {
          headerMap.set(header, index)
        })

        preparedExportData.value = {
          workbook: wb,
          ready: true,
          config: {
            headers1,
            headerMap,
            sortFieldIndices,
            totalRows: excel1Data.length - 1,
          },
        }
      } else {
        preparedExportData.value = {
          workbook: wb,
          ready: true,
          config: null,
        }
      }
    } catch (error) {
      console.error('准备导出数据失败:', error)
      preparedExportData.value.ready = false
    }
  }

  // 下载Excel格式的对比结果
  const downloadResults = async (
    comparisonResult: ComparisonResult | null,
    excel1Data: any[],
    excel2Data: any[],
    columnConfigs: ColumnConfig[],
    sortConfigs: SortConfig[],
    compareMode: string,
  ) => {
    if (!comparisonResult || !excel1Data.length) return

    if (preparedExportData.value.ready && preparedExportData.value.workbook) {
      try {
        showDownloadAnimation.value = true
        downloadProgress.value = 10
        downloadStage.value = '准备导出数据...'

        const wb = preparedExportData.value.workbook
        const config = preparedExportData.value.config

        if (config) {
          downloadStage.value = '创建详细对比工作表...'
          downloadProgress.value = 20

          const { headers1, headerMap, sortFieldIndices, totalRows } = config

          const columnsToCompare = columnConfigs
            .filter((config) => config.shouldCompare)
            .map((config) => config.name)

          const filteredHeaders = headers1.filter(
            (header) =>
              columnsToCompare.includes(header) ||
              sortFieldIndices.includes(headers1.indexOf(header)),
          )
          const detailWs = XLSX.utils.aoa_to_sheet([filteredHeaders])

          const BATCH_SIZE = 500
          const batchCount = Math.ceil(totalRows / BATCH_SIZE)

          for (let batch = 0; batch < batchCount; batch++) {
            const progressPercent = 20 + Math.floor((batch / batchCount) * 70)
            downloadProgress.value = progressPercent
            downloadStage.value = `处理数据 ${batch * BATCH_SIZE + 1}-${Math.min((batch + 1) * BATCH_SIZE, totalRows)} / ${totalRows}...`

            const startRow = batch * BATCH_SIZE + 1
            const endRow = Math.min((batch + 1) * BATCH_SIZE, excel1Data.length - 1) + 1

            await new Promise((resolve) => setTimeout(resolve, 0))

            for (let i = startRow; i < endRow; i++) {
              const row1 = excel1Data[i]
              if (!row1) continue

              const newRow: any[] = []
              for (let k = 0; k < filteredHeaders.length; k++) {
                newRow.push(null)
              }

              let matchingRow2: any[] | null = null

              if (compareMode === 'key') {
                if (sortFieldIndices.length > 0) {
                  const keyValue = sortFieldIndices
                    .map((idx) => normalizeValue(row1[idx]))
                    .join('_')

                  matchingRow2 =
                    excel2Data.find((r: any[], idx: number) => {
                      if (idx > 0 && r) {
                        const rowKey = sortFieldIndices
                          .map((i) => {
                            const headerName = headers1[i]
                            const excel2Index = headerMap.get(headerName)
                            return excel2Index !== undefined ? normalizeValue(r[excel2Index]) : ''
                          })
                          .join('_')
                        return rowKey === keyValue
                      }
                      return false
                    }) || null
                }
              } else {
                matchingRow2 = excel2Data && i < excel2Data.length ? excel2Data[i] : null
              }

              filteredHeaders.forEach((headerName, filteredIndex) => {
                const originalIndex = headers1.indexOf(headerName)
                if (originalIndex === -1) return

                const value1 = row1[originalIndex]

                if (sortFieldIndices.includes(originalIndex)) {
                  newRow[filteredIndex] = value1
                  return
                }

                const excel2ColIndex = headerMap.get(headerName)

                if (excel2ColIndex === undefined) {
                  newRow[filteredIndex] = `${value1} [Excel2不存在]`
                } else if (!matchingRow2) {
                  newRow[filteredIndex] = `${value1} [仅在Excel1中]`
                } else {
                  const value2 = matchingRow2[excel2ColIndex]
                  let val1 = value1
                  let val2 = value2

                  const colConfig = columnConfigs.find((c) => c.name === headerName)
                  if (colConfig && colConfig.isNumeric && colConfig.ignoreDigits > 0) {
                    if (typeof val1 === 'number' && typeof val2 === 'number') {
                      const factor = Math.pow(10, colConfig.ignoreDigits)
                      val1 = Math.floor(val1 * factor) / factor
                      val2 = Math.floor(val2 * factor) / factor
                    }
                  }

                  if (normalizeValue(val1) === normalizeValue(val2)) {
                    newRow[filteredIndex] = `${value1} [完全一致]`
                  } else {
                    newRow[filteredIndex] = `${value1} [Excel1:${val1}, Excel2:${val2}]`
                  }
                }
              })

              const rowIndex = i - startRow + 1 + batch * BATCH_SIZE + 1
              XLSX.utils.sheet_add_aoa(detailWs, [newRow], { origin: rowIndex })
            }
          }

          XLSX.utils.book_append_sheet(wb, detailWs, 'Excel1详细对比')
        }

        downloadStage.value = '生成Excel文件...'
        downloadProgress.value = 95
        await new Promise((resolve) => setTimeout(resolve, 300))

        XLSX.writeFile(wb, 'excel_comparison_result.xlsx')

        downloadProgress.value = 100
        downloadStage.value = '导出完成！'
        await new Promise((resolve) => setTimeout(resolve, 500))

        showDownloadAnimation.value = false
        ElMessage.success('对比结果已下载')
      } catch (error) {
        console.error('下载失败:', error)
        ElMessage.error('下载失败，请重试')
        showDownloadAnimation.value = false
      }
      return
    }

    // 如果没有预处理数据，执行原来的完整处理逻辑
    showDownloadAnimation.value = true
    downloadProgress.value = 0
    downloadStage.value = '准备导出数据...'

    const progressInterval = setInterval(() => {
      if (downloadProgress.value < 90) {
        downloadProgress.value += Math.random() * 8
        if (downloadProgress.value > 90) downloadProgress.value = 90
      }
    }, 300)

    try {
      await new Promise((resolve) => setTimeout(resolve, 300))

      downloadStage.value = '创建结果摘要...'
      downloadProgress.value = 15
      const wb = XLSX.utils.book_new()

      const summaryData = [
        ['Excel对比结果摘要'],
        [''],
        ['总行数', comparisonResult.totalRows],
        ['相同行数', comparisonResult.matchedRows],
        ['不同行数', comparisonResult.differentRows],
        ['文件1独有', comparisonResult.onlyInFile1],
        ['文件2独有', comparisonResult.onlyInFile2],
      ]
      const summaryWs = XLSX.utils.aoa_to_sheet(summaryData)
      XLSX.utils.book_append_sheet(wb, summaryWs, '对比摘要')

      downloadStage.value = '整理差异数据...'
      downloadProgress.value = 30
      await new Promise((resolve) => setTimeout(resolve, 200))

      const diffData = [
        ['行号', '差异类型', '文件1内容', '文件2内容'],
        ...comparisonResult.differences.map((diff) => [
          diff.row,
          getDiffTypeText(diff.type),
          diff.content1 || '',
          diff.content2 || '',
        ]),
      ]
      const diffWs = XLSX.utils.aoa_to_sheet(diffData)
      XLSX.utils.book_append_sheet(wb, diffWs, '详细差异')

      downloadStage.value = '生成Excel文件...'
      downloadProgress.value = 95
      await new Promise((resolve) => setTimeout(resolve, 300))

      XLSX.writeFile(wb, 'excel_comparison_result.xlsx')

      downloadProgress.value = 100
      downloadStage.value = '导出完成！'
      await new Promise((resolve) => setTimeout(resolve, 500))

      showDownloadAnimation.value = false
      ElMessage.success('对比结果已下载')
    } catch (error) {
      console.error('下载失败:', error)
      ElMessage.error('下载失败，请重试')
      showDownloadAnimation.value = false
    } finally {
      clearInterval(progressInterval)
    }
  }

  // 下载CSV格式的对比结果
  const downloadResultsAsCsv = async (
    comparisonResult: ComparisonResult | null,
    excel1Data: any[],
    columnConfigs: ColumnConfig[],
    sortConfigs: SortConfig[],
  ) => {
    if (!comparisonResult || !excel1Data.length) return

    showDownloadAnimation.value = true
    downloadProgress.value = 10
    downloadStage.value = '准备导出CSV数据...'

    try {
      const headers1 = excel1Data[0] || []

      const sortFieldIndices: number[] = []
      for (const config of sortConfigs) {
        const index = headers1.findIndex((h: string) => h === config.field)
        if (index !== -1) {
          sortFieldIndices.push(index)
        }
      }

      const columnsToCompare = columnConfigs
        .filter((config) => config.shouldCompare)
        .map((config) => config.name)

      let csvContent = '"行号","排序字段","差异类型","差异内容"\n'

      const totalItems = comparisonResult.differences.length
      const BATCH_SIZE = 1000
      const batchCount = Math.ceil(totalItems / BATCH_SIZE)

      const escapeCSV = (field: string) => {
        const escaped = field.replace(/"/g, '""')
        return escaped.includes(',') || escaped.includes('\n') || escaped.includes('"')
          ? `"${escaped}"`
          : escaped
      }

      for (let batch = 0; batch < batchCount; batch++) {
        const progressPercent = 20 + Math.floor((batch / batchCount) * 70)
        downloadProgress.value = progressPercent
        downloadStage.value = `处理数据 ${batch * BATCH_SIZE + 1}-${Math.min((batch + 1) * BATCH_SIZE, totalItems)} / ${totalItems}...`

        await new Promise((resolve) => setTimeout(resolve, 0))

        const startIndex = batch * BATCH_SIZE
        const endIndex = Math.min((batch + 1) * BATCH_SIZE, totalItems)

        for (let i = startIndex; i < endIndex; i++) {
          const diff = comparisonResult.differences[i]

          let sortFieldValues = '无排序字段'

          if (diff.type === 'only-in-file1' && diff.content1) {
            try {
              const row = JSON.parse(diff.content1)
              if (sortFieldIndices.length > 0) {
                sortFieldValues = sortFieldIndices
                  .map((idx) => {
                    const fieldName = headers1[idx]
                    return `${fieldName}:${row[idx] || '空值'}`
                  })
                  .join('; ')
              }
            } catch (e) {
              console.error('解析失败:', e)
            }
          } else if (diff.type === 'only-in-file2' && diff.content2) {
            sortFieldValues = '仅在Excel2中'
          } else if (diff.type === 'different' && diff.content1) {
            try {
              const row = JSON.parse(diff.content1)
              if (sortFieldIndices.length > 0) {
                sortFieldValues = sortFieldIndices
                  .map((idx) => {
                    const fieldName = headers1[idx]
                    return `${fieldName}:${row[idx] || '空值'}`
                  })
                  .join('; ')
              }
            } catch (e) {
              console.error('解析失败:', e)
            }
          }

          let diffContent = '-'
          if (diff.type === 'different') {
            try {
              const row1 = diff.content1 ? JSON.parse(diff.content1) : null
              const row2 = diff.content2 ? JSON.parse(diff.content2) : null

              if (row1 && row2) {
                const diffFields = []
                for (let j = 0; j < headers1.length; j++) {
                  if (sortFieldIndices.includes(j) || !columnsToCompare.includes(headers1[j]))
                    continue

                  if (normalizeValue(row1[j]) !== normalizeValue(row2[j])) {
                    diffFields.push(
                      `${headers1[j]} Excel1:${row1[j] || '空值'} Excel2:${row2[j] || '空值'}`,
                    )
                  }
                }
                diffContent = diffFields.join('; ')
              }
            } catch (e) {
              console.error('解析差异内容失败:', e)
              diffContent = '解析失败'
            }
          } else if (diff.type === 'only-in-file1') {
            diffContent = '仅在Excel1中存在'
          } else if (diff.type === 'only-in-file2') {
            diffContent = '仅在Excel2中存在'
          }

          csvContent += `${escapeCSV(String(diff.row))},${escapeCSV(sortFieldValues)},${escapeCSV(getDiffTypeText(diff.type))},${escapeCSV(diffContent)}\n`
        }
      }

      downloadStage.value = '生成CSV文件...'
      downloadProgress.value = 95
      await new Promise((resolve) => setTimeout(resolve, 300))

      const BOM = '\uFEFF'
      const blob = new Blob([BOM + csvContent], { type: 'text/csv;charset=utf-8' })
      const url = URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = url
      link.download = 'excel_comparison_result.csv'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      URL.revokeObjectURL(url)

      downloadProgress.value = 100
      downloadStage.value = '导出完成！'
      await new Promise((resolve) => setTimeout(resolve, 500))
      showDownloadAnimation.value = false

      ElMessage.success('对比结果已下载为CSV格式')
    } catch (error) {
      console.error('下载失败:', error)
      ElMessage.error('下载失败，请重试')
      showDownloadAnimation.value = false
    }
  }

  return {
    // 状态
    showDownloadAnimation,
    downloadProgress,
    downloadStage,
    preparedExportData,

    // 方法
    prepareExportData,
    downloadResults,
    downloadResultsAsCsv,
    getDiffTypeText,
  }
}
